package io.nads.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.Map;
import java.util.Optional;

/**
 * HTTP请求工具类
 * 抽取QiniuTTS和QiniuASR中重复的HTTP请求代码
 */
@Slf4j
public class HttpRequestUtil {
    
    /**
     * 判断HTTP状态码是否可重试
     * @param statusCode HTTP状态码
     * @return 是否可重试
     */
    private static boolean isRetryableStatus(int statusCode) {
        // 5xx服务器错误、408请求超时、429请求过多、502网关错误、503服务不可用、504网关超时
        return statusCode >= 500 || statusCode == 408 || statusCode == 429 || statusCode == 502 || statusCode == 503 || statusCode == 504;
    }
    
    /**
     * 发送带Bearer Token认证的GET请求（带重试机制）
     * @param url 请求URL
     * @param apiKey API密钥
     * @param userAgent 用户代理
     * @param logPrefix 日志前缀
     * @return 响应结果
     */
    public static JSONObject getWithBearerToken(String url, String apiKey, String userAgent, String logPrefix) {
        int maxRetries = 5;
        int retryCount = 0;
        
        while (retryCount <= maxRetries) {
            try {
                if (retryCount > 0) {
                    log.info("{} GET请求第{}次重试", logPrefix, retryCount);
                    // 重试前等待，使用指数退避策略
                    Thread.sleep(Math.min(1000 * (1L << (retryCount - 1)), 10000));
                }
                
                HttpResponse response = HttpRequest.get(url)
                        .header("Authorization", "Bearer " + apiKey)
                        .header("User-Agent", userAgent)
                        .timeout(30000) // 30秒超时
                        .setConnectionTimeout(10000) // 10秒连接超时
                        .setReadTimeout(30000) // 30秒读取超时
                        .disableCache()
                        .execute();
                
                log.info("{} GET请求响应状态: {}", logPrefix, response.getStatus());
                
                if (response.getStatus() == 200) {
                    String responseBody = response.body();
                    log.info("{} GET请求响应: {}", logPrefix, responseBody);
                    
                    // 检查响应是否是数组格式
                    if (responseBody.trim().startsWith("[")) {
                        // 如果是数组，包装成对象格式
                        JSONObject wrapper = new JSONObject();
                        try {
                            wrapper.set("data", JSONUtil.parseArray(responseBody));
                        } catch (Exception e) {
                            log.warn("{} 解析JSON数组失败，将作为字符串处理: {}", logPrefix, e.getMessage());
                            wrapper.set("data", responseBody);
                        }
                        return wrapper;
                    } else {
                        return JSONUtil.parseObj(responseBody);
                    }
                } else if (isRetryableStatus(response.getStatus()) && retryCount < maxRetries) {
                    log.warn("{} GET请求失败，状态码: {}，将进行重试 ({}/{})", 
                            logPrefix, response.getStatus(), retryCount + 1, maxRetries);
                    retryCount++;
                    continue;
                } else {
                    log.error("{} GET请求失败，状态码: {}, 响应: {}", logPrefix, response.getStatus(), response.body());
                    return null;
                }
            } catch (Exception e) {
                if (retryCount < maxRetries) {
                    log.warn("{} GET请求异常，将进行重试 ({}/{}): {}", 
                            logPrefix, retryCount + 1, maxRetries, e.getMessage());
                    retryCount++;
                    continue;
                } else {
                    log.error("{} GET请求异常，已达到最大重试次数", logPrefix, e);
                    return null;
                }
            }
        }
        
        log.error("{} GET请求失败，已达到最大重试次数: {}", logPrefix, maxRetries);
        return null;
    }
    
    /**
     * 发送带Bearer Token认证的POST请求（带重试机制）
     * @param url 请求URL
     * @param data 请求数据
     * @param apiKey API密钥
     * @param userAgent 用户代理
     * @param logPrefix 日志前缀
     * @return 响应结果
     */
    public static JSONObject postWithBearerToken(String url, Map<String, Object> data, String apiKey, String userAgent, String logPrefix) {
        int maxRetries = 5;
        int retryCount = 0;
        
        while (retryCount <= maxRetries) {
            try {
                if (retryCount > 0) {
                    log.info("{} POST请求第{}次重试", logPrefix, retryCount);
                    // 重试前等待，使用指数退避策略
                    Thread.sleep(Math.min(1000 * (1L << (retryCount - 1)), 10000));
                }
                
                // 构建请求体
                String jsonBody = JSONUtil.toJsonStr(data);
                
                // 发送HTTP请求，使用Bearer Token认证
                HttpResponse response = HttpRequest.post(url)
                        .header("Authorization", "Bearer " + apiKey)
                        .header("Content-Type", "application/json")
                        .header("User-Agent", userAgent)
                        .body(jsonBody)
                        .timeout(90000) // 90秒超时
                        .setConnectionTimeout(30000) // 30秒连接超时
                        .setReadTimeout(60000) // 60秒读取超时
                        .disableCache()
                        .execute();
                
                log.info("{} POST请求响应状态: {}", logPrefix, response.getStatus());
                
                if (response.getStatus() == 200) {
                    String responseBody = response.body();
                    log.info("{} POST请求响应: {}", logPrefix, responseBody.substring(0, Math.min(20, responseBody.length())) + "...");
                    return JSONUtil.parseObj(responseBody);
                } else if (isRetryableStatus(response.getStatus()) && retryCount < maxRetries) {
                    log.warn("{} POST请求失败，状态码: {}，将进行重试 ({}/{})", 
                            logPrefix, response.getStatus(), retryCount + 1, maxRetries);
                    retryCount++;
                    continue;
                } else {
                    log.error("{} POST请求失败，状态码: {}, 响应: {}", logPrefix, response.getStatus(), response.body());
                    return null;
                }
            } catch (Exception e) {
                if (retryCount < maxRetries) {
                    log.warn("{} POST请求异常，将进行重试 ({}/{}): {}", 
                            logPrefix, retryCount + 1, maxRetries, e.getMessage());
                    retryCount++;
                    continue;
                } else {
                    log.error("{} POST请求异常，已达到最大重试次数", logPrefix, e);
                    return null;
                }
            }
        }
        
        log.error("{} POST请求失败，已达到最大重试次数: {}", logPrefix, maxRetries);
        return null;
    }
    
    /**
     * 发送带Bearer Token认证的POST请求（用于ASR，带重试机制）
     * @param url 请求URL
     * @param file 音频文件
     * @param apiKey API密钥
     * @param userAgent 用户代理
     * @param logPrefix 日志前缀
     * @return 响应结果
     */
    public static JSONObject postWithBearerTokenForASR(String url, File file, String apiKey, String userAgent, String logPrefix) {
        int maxRetries = 5;
        int retryCount = 0;
        
        while (retryCount <= maxRetries) {
            try {
                if (retryCount > 0) {
                    log.info("{} ASR POST请求第{}次重试", logPrefix, retryCount);
                    // 重试前等待，使用指数退避策略
                    Thread.sleep(Math.min(1000 * (1L << (retryCount - 1)), 10000));
                }
                
                // 发送HTTP请求，使用Bearer Token认证
                HttpResponse response = HttpRequest.post(url)
                        .header("Authorization", "Bearer " + apiKey)
                        .header("User-Agent", userAgent)
                        .form("file", file)
                        .timeout(90000) // 90秒超时
                        .setConnectionTimeout(30000) // 30秒连接超时
                        .setReadTimeout(60000) // 60秒读取超时
                        .disableCache()
                        .execute();
                
                log.info("{} ASR POST请求响应状态: {}", logPrefix, response.getStatus());
                
                if (response.getStatus() == 200) {
                    String responseBody = response.body();
                    log.info("{} ASR POST请求响应: {}", logPrefix, responseBody.substring(0, Math.min(20, responseBody.length())) + "...");
                    return JSONUtil.parseObj(responseBody);
                } else if (isRetryableStatus(response.getStatus()) && retryCount < maxRetries) {
                    log.warn("{} ASR POST请求失败，状态码: {}，将进行重试 ({}/{})", 
                            logPrefix, response.getStatus(), retryCount + 1, maxRetries);
                    retryCount++;
                    continue;
                } else {
                    log.error("{} ASR POST请求失败，状态码: {}, 响应: {}", logPrefix, response.getStatus(), response.body());
                    return null;
                }
            } catch (Exception e) {
                if (retryCount < maxRetries) {
                    log.warn("{} ASR POST请求异常，将进行重试 ({}/{}): {}", 
                            logPrefix, retryCount + 1, maxRetries, e.getMessage());
                    retryCount++;
                    continue;
                } else {
                    log.error("{} ASR POST请求异常，已达到最大重试次数", logPrefix, e);
                    return null;
                }
            }
        }
        
        log.error("{} ASR POST请求失败，已达到最大重试次数: {}", logPrefix, maxRetries);
        return null;
    }
}